package handler

import (
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/slrun/callcenter/internal/model"
	"github.com/slrun/callcenter/internal/service"
)

// MonitorHandler 监控处理器
type MonitorHandler struct {
	Services *service.Services
}

// NewMonitorHandler 创建监控处理器实例
func NewMonitorHandler(services *service.Services) *MonitorHandler {
	return &MonitorHandler{
		Services: services,
	}
}

// GetRealTimeMonitor 获取实时监控数据
func (h *MonitorHandler) GetRealTimeMonitor(c *gin.Context) {
	monitor, err := h.Services.MonitorService.GetRealTimeMonitor()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取实时监控数据失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, monitor)
}

// GetCallReport 获取呼叫报表
func (h *MonitorHandler) GetCallReport(c *gin.Context) {
	// 解析日期参数
	startDateStr := c.Query("start_date")
	endDateStr := c.Query("end_date")
	periodStr := c.DefaultQuery("period", "daily")
	
	// 解析起始日期
	startDate, err := time.Parse("2006-01-02", startDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "起始日期格式错误，请使用YYYY-MM-DD格式"})
		return
	}
	
	// 解析结束日期
	endDate, err := time.Parse("2006-01-02", endDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "结束日期格式错误，请使用YYYY-MM-DD格式"})
		return
	}
	
	// 确保结束日期包含整天
	endDate = endDate.Add(24*time.Hour - time.Second)
	
	// 验证日期范围
	if endDate.Before(startDate) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "结束日期不能早于起始日期"})
		return
	}
	
	// 验证日期范围不能超过90天
	maxDuration := 90 * 24 * time.Hour
	if endDate.Sub(startDate) > maxDuration {
		c.JSON(http.StatusBadRequest, gin.H{"error": "日期范围不能超过90天"})
		return
	}
	
	// 解析报表周期
	period := model.ReportPeriod(periodStr)
	if !isValidPeriod(period) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "报表周期无效，可选值：hourly, daily, weekly, monthly"})
		return
	}
	
	// 生成报表
	reportData, err := h.Services.MonitorService.GenerateCallReport(startDate, endDate, period)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "生成呼叫报表失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"start_date": startDate.Format("2006-01-02"),
		"end_date":   endDate.Format("2006-01-02"),
		"period":     period,
		"data":       reportData,
	})
}

// GetAgentReport 获取座席报表
func (h *MonitorHandler) GetAgentReport(c *gin.Context) {
	// 解析日期参数
	startDateStr := c.Query("start_date")
	endDateStr := c.Query("end_date")
	agentIDs := c.QueryArray("agent_ids")
	
	// 解析起始日期
	startDate, err := time.Parse("2006-01-02", startDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "起始日期格式错误，请使用YYYY-MM-DD格式"})
		return
	}
	
	// 解析结束日期
	endDate, err := time.Parse("2006-01-02", endDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "结束日期格式错误，请使用YYYY-MM-DD格式"})
		return
	}
	
	// 确保结束日期包含整天
	endDate = endDate.Add(24*time.Hour - time.Second)
	
	// 验证日期范围
	if endDate.Before(startDate) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "结束日期不能早于起始日期"})
		return
	}
	
	// 验证日期范围不能超过30天
	maxDuration := 30 * 24 * time.Hour
	if endDate.Sub(startDate) > maxDuration {
		c.JSON(http.StatusBadRequest, gin.H{"error": "座席报表日期范围不能超过30天"})
		return
	}
	
	// 生成报表
	reportData, err := h.Services.MonitorService.GenerateAgentReport(startDate, endDate, agentIDs)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "生成座席报表失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"start_date": startDate.Format("2006-01-02"),
		"end_date":   endDate.Format("2006-01-02"),
		"agent_ids":  agentIDs,
		"data":       reportData,
	})
}

// GetQueueReport 获取队列报表
func (h *MonitorHandler) GetQueueReport(c *gin.Context) {
	// 解析日期参数
	startDateStr := c.Query("start_date")
	endDateStr := c.Query("end_date")
	queueIDs := c.QueryArray("queue_ids")
	
	// 解析起始日期
	startDate, err := time.Parse("2006-01-02", startDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "起始日期格式错误，请使用YYYY-MM-DD格式"})
		return
	}
	
	// 解析结束日期
	endDate, err := time.Parse("2006-01-02", endDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "结束日期格式错误，请使用YYYY-MM-DD格式"})
		return
	}
	
	// 确保结束日期包含整天
	endDate = endDate.Add(24*time.Hour - time.Second)
	
	// 验证日期范围
	if endDate.Before(startDate) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "结束日期不能早于起始日期"})
		return
	}
	
	// 验证日期范围不能超过90天
	maxDuration := 90 * 24 * time.Hour
	if endDate.Sub(startDate) > maxDuration {
		c.JSON(http.StatusBadRequest, gin.H{"error": "日期范围不能超过90天"})
		return
	}
	
	// 生成报表
	reportData, err := h.Services.MonitorService.GenerateQueueReport(startDate, endDate, queueIDs)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "生成队列报表失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{
		"start_date": startDate.Format("2006-01-02"),
		"end_date":   endDate.Format("2006-01-02"),
		"queue_ids":  queueIDs,
		"data":       reportData,
	})
}

// CreateDashboardItem 创建仪表盘项目
func (h *MonitorHandler) CreateDashboardItem(c *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权访问"})
		return
	}
	
	var item model.DashboardItem
	if err := c.ShouldBindJSON(&item); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求数据格式错误", "details": err.Error()})
		return
	}
	
	// 验证数据
	if item.Title == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "仪表盘项目标题不能为空"})
		return
	}
	
	if item.Type == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "仪表盘项目类型不能为空"})
		return
	}
	
	// 创建仪表盘项目
	createdItem, err := h.Services.MonitorService.CreateDashboardItem(userID.(string), item)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建仪表盘项目失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusCreated, createdItem)
}

// GetDashboardItems 获取用户的仪表盘项目
func (h *MonitorHandler) GetDashboardItems(c *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权访问"})
		return
	}
	
	items, err := h.Services.MonitorService.GetDashboardItems(userID.(string))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取仪表盘项目失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, items)
}

// UpdateDashboardItem 更新仪表盘项目
func (h *MonitorHandler) UpdateDashboardItem(c *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权访问"})
		return
	}
	
	// 获取项目ID
	itemID := c.Param("id")
	if itemID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "仪表盘项目ID不能为空"})
		return
	}
	
	var updates map[string]interface{}
	if err := c.ShouldBindJSON(&updates); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求数据格式错误", "details": err.Error()})
		return
	}
	
	// 更新仪表盘项目
	updatedItem, err := h.Services.MonitorService.UpdateDashboardItem(userID.(string), itemID, updates)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新仪表盘项目失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, updatedItem)
}

// DeleteDashboardItem 删除仪表盘项目
func (h *MonitorHandler) DeleteDashboardItem(c *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权访问"})
		return
	}
	
	// 获取项目ID
	itemID := c.Param("id")
	if itemID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "仪表盘项目ID不能为空"})
		return
	}
	
	// 删除仪表盘项目
	if err := h.Services.MonitorService.DeleteDashboardItem(userID.(string), itemID); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除仪表盘项目失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, gin.H{"message": "仪表盘项目删除成功"})
}

// CreateAlert 创建监控告警
func (h *MonitorHandler) CreateAlert(c *gin.Context) {
	var alert model.MonitorAlert
	if err := c.ShouldBindJSON(&alert); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求数据格式错误", "details": err.Error()})
		return
	}
	
	// 验证数据
	if alert.Name == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "告警名称不能为空"})
		return
	}
	
	if alert.Metric == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "监控指标不能为空"})
		return
	}
	
	if alert.Condition == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "告警条件不能为空"})
		return
	}
	
	if alert.Severity == "" {
		alert.Severity = "warning" // 默认警告级别
	}
	
	// 创建告警
	createdAlert, err := h.Services.MonitorService.CreateAlert(alert)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建告警失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusCreated, createdAlert)
}

// GetAlerts 获取告警列表
func (h *MonitorHandler) GetAlerts(c *gin.Context) {
	// 解析active_only参数
	activeOnlyStr := c.DefaultQuery("active_only", "true")
	activeOnly, err := strconv.ParseBool(activeOnlyStr)
	if err != nil {
		activeOnly = true // 默认只获取活跃告警
	}
	
	alerts, err := h.Services.MonitorService.GetAlerts(activeOnly)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取告警列表失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, alerts)
}

// UpdateAlert 更新告警
func (h *MonitorHandler) UpdateAlert(c *gin.Context) {
	// 获取告警ID
	alertID := c.Param("id")
	if alertID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "告警ID不能为空"})
		return
	}
	
	var updates map[string]interface{}
	if err := c.ShouldBindJSON(&updates); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求数据格式错误", "details": err.Error()})
		return
	}
	
	// 更新告警
	updatedAlert, err := h.Services.MonitorService.UpdateAlert(alertID, updates)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新告警失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, updatedAlert)
}

// GetAlertEvents 获取告警事件
func (h *MonitorHandler) GetAlertEvents(c *gin.Context) {
	// 获取告警ID
	alertID := c.Query("alert_id")
	
	// 解析limit参数
	limitStr := c.DefaultQuery("limit", "100")
	limit, err := strconv.Atoi(limitStr)
	if err != nil || limit <= 0 {
		limit = 100 // 默认限制100条
	}
	
	events, err := h.Services.MonitorService.GetAlertEvents(alertID, limit)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取告警事件失败", "details": err.Error()})
		return
	}
	
	c.JSON(http.StatusOK, events)
}

// 验证报表周期是否有效
func isValidPeriod(period model.ReportPeriod) bool {
	switch period {
	case model.ReportPeriodHourly, model.ReportPeriodDaily, model.ReportPeriodWeekly, model.ReportPeriodMonthly:
		return true
	default:
		return false
	}
}